const { Service } = require('egg');
const { v4 } = require('uuid');
const moment = require('moment');

const table_name = 'file_cloud',
  user_table = 'user';

class CloudService extends Service {

  async insert(name, host, port, path, info, type) {
    const { ctx, app } = this;
    try {
      const { id: user_id } = ctx.session;
      const is_exist = await ctx.app.knex(table_name).select('uuid').where({ host, port, type })
        .first();

      if (is_exist) {
        throw new Error('存储空间已经存在');
      }
      const time = moment();
      const instance = {
        uuid: v4(),
        name, host, port, path, info, type,
        create_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
        update_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
        create_by: user_id,
        update_by: user_id,
      };

      await ctx.app.knex(table_name).insert(instance);

      return instance;
    } catch (error) {
      throw error;
    }
  }

  async list(host, port, name, path, type, order, method, pageSize, pageIndex) {
    const { ctx, app } = this;
    try {
      const listSql = ctx.app.knex(`${table_name} as t1`).select('t1.uuid', 't1.name', 't1.host', 't1.path', 't1.info', 't1.type',
        't1.create_time', 't1.update_time', 't2.name as create_name', 't3.name as update_name')
        .leftJoin(`${user_table} as t2`, function() {
          this.on('t1.create_by', '=', 't2.uuid');
        })
        .leftJoin(`${user_table} as t3`, function() {
          this.on('t1.update_by', '=', 't3.uuid');
        })
        .where('t1.is_delete', '=', 0);

      const countSql = ctx.app.knex(table_name).count('uuid as count').where({ is_delete: 0 });


      if (host) {
        listSql.andWhereLike('t1.host', `%${host}%`);
        countSql.andWhereLike('host', `%${host}%`);
      }

      if (port) {
        listSql.andWhereLike('t1.port', `%${port}%`);
        countSql.andWhereLike('port', `%${port}%`);
      }

      if (name) {
        listSql.andWhereLike('t1.name', `%${name}%`);
        countSql.andWhereLike('name', `%${name}%`);
      }

      if (path) {
        listSql.andWhereLike('t1.path', `%${path}%`);
        countSql.andWhereLike('path', `%${path}%`);
      }

      if (type) {
        listSql.andWhereLike('t1.path', `%${type}%`);
        countSql.andWhereLike('path', `%${type}%`);
      }

      const list = await listSql.orderBy(`t1.${order}`, method).limit(Number(pageSize)).offset((Number(pageIndex - 1) * Number(pageSize)));
      const count = await countSql.first();


      return {
        list,
        count,
      };
    } catch (error) {
      throw error;
    }
  }

  async info(uuid) {
    const { app, ctx } = this;
    try {
      const info = await ctx.app.knex(table_name).select('name', 'host', 'port', 'path', 'info', 'type').where({ uuid });
      return info;
    } catch (error) {
      throw error;
    }
  }


  async update(name, host, port, path, info, type, uuid) {
    const { ctx, app } = this;

    try {
      const time = moment();
      const is_exist = await ctx.app.knex(table_name).select('*').where({ uuid })
        .first();

      const { id: user_id } = ctx.session;
      const instance = {
        update_by: user_id,
        update_time: moment(time),
      };
      if (is_exist) {
        if (name) {
          instance.name = name;
        }

        if (host) {
          instance.host = host;
        }

        if (port) {
          instance.port = port;
        }
        if (path) {
          instance.path = info;
        }
        if (info) {
          instance.info = info;
        }

        if (type) {
          instance.type = type;
        }

        await ctx.app.knex(table_name).update(instance).where({ uuid });
      }

      return instance;
    } catch (error) {
      throw error;
    }
  }


  async delete(ids) {
    const { ctx, app } = this;
    try {
      const { id: user_id } = ctx.session;
      const time = moment();
      const instances = {
        is_delete: 1,
        update_by: user_id,
        update_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
      };

      await ctx.app.knex(table_name).update(instances).whereIn('uuid', ids);

      return instances;
    } catch (error) {
      throw error;
    }
  }

  async setDefault(uuid) {
    const { ctx, app } = this;
    const trx = await ctx.app.knex.transaction();
    try {
      const { id: user_id } = ctx.session;
      const time = moment();
      const is_exist = await ctx.app.knex(table_name).select('uuid').where({ default: 0 })
        .first();
      // 判断当前是否拥有默认上传云
      if (is_exist) {
        const updateInstance = {
          default: 1,
          update_by: user_id,
          update_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
        };

        await trx(table_name).update(updateInstance).where({ uuid: is_exist.uuid });
      }

      const instance = {
        default: 0,
        update_by: user_id,
        update_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
      };

      await trx(table_name).update(instance).where({ uuid });

      await trx.commit();
      return instance;
    } catch (error) {
      await trx.rollback();
      throw error;
    }
  }

  async getDefault() {
    const ctx = this.ctx;
    try {
      const result = await ctx.app.knex(table_name).select('*').where({ default: 0 })
        .first();

      if (!result) {
        throw new Error('当前尚未配置文件服务');
      }
      return result;
    } catch (error) {
      throw error;
    }
  }
}

module.exports = CloudService;
